const halo = document.getElementById("halo");
const haloStatus = document.getElementById("halo-status");
const haloHint = document.querySelector(".halo-hint");
const statusText = document.getElementById("status-text");
const startBtn = document.getElementById("start-btn");
const lastTimeEl = document.getElementById("last-time");
const avgTimeEl = document.getElementById("avg-time");
const bestTimeEl = document.getElementById("best-time");
const countEl = document.getElementById("count-total");
const historyList = document.getElementById("history-list");
const topList = document.getElementById("top-list");

const state = {
    waiting: false,
    active: false,
    timer: null,
    startTime: 0,
};

const initialStats = window.__INITIAL_STATS__ || {};
updateStats(initialStats);
setHaloState("ready", "准备中", "点击按钮开始");

startBtn.addEventListener("click", startTest);
halo.addEventListener("click", handleHaloClick);
halo.addEventListener("keydown", (event) => {
    if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        handleHaloClick();
    }
});

function startTest() {
    if (state.waiting || state.active) {
        return;
    }
    state.waiting = true;
    setHaloState("waiting", "等待", "保持冷静");
    statusText.textContent = "光环将在随机时间发光，提前点击将被判定为抢跑。";
    startBtn.disabled = true;

    const delay = 1200 + Math.random() * 2500;
    state.timer = setTimeout(() => {
        state.waiting = false;
        state.active = true;
        state.startTime = performance.now();
        setHaloState("active", "点击！", "光环已亮起");
        statusText.textContent = "现在点击光环或按空格测出你的反应时间。";
    }, delay);
}

function handleHaloClick() {
    if (state.waiting) {
        resetRound();
        statusText.textContent = "太快了！等光环亮起后再点击。";
        halo.classList.add("shake");
        setTimeout(() => halo.classList.remove("shake"), 600);
        return;
    }

    if (!state.active) {
        return;
    }

    const reaction = performance.now() - state.startTime;
    finishRound(reaction);
}

function finishRound(reaction) {
    resetRound();
    setHaloState("ready", "记录中", "请稍候");
    statusText.textContent = `成绩 ${reaction.toFixed(0)} ms，正在写入服务器...`;

    fetch("/api/results", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ reaction_time: reaction }),
    })
        .then((res) => res.json())
        .then((payload) => {
            if (!payload.ok) {
                throw new Error(payload.error || "未知错误");
            }
            updateStats(payload.data);
            lastTimeEl.textContent = `${reaction.toFixed(0)} ms`;
            statusText.textContent = "完成！再来一次挑战更快的反应速度吧。";
            setHaloState("ready", "完成", "点击按钮再次开始");
        })
        .catch((err) => {
            console.error(err);
            statusText.textContent = "写入失败，请检查服务器日志。";
            setHaloState("ready", "失败", "稍后重试");
        })
        .finally(() => {
            startBtn.disabled = false;
        });
}

function resetRound() {
    clearTimeout(state.timer);
    state.waiting = false;
    state.active = false;
}

function setHaloState(mode, status, hint) {
    halo.classList.remove("ready", "waiting", "active");
    halo.classList.add(mode);
    haloStatus.textContent = status;
    haloHint.textContent = hint;
}

function updateStats(stats) {
    if (!stats) {
        return;
    }
    const fmt = (value, unit = "ms") => (value || value === 0 ? `${Math.round(value)} ${unit}` : "--");
    lastTimeEl.textContent = fmt(stats.last);
    avgTimeEl.textContent = fmt(stats.average);
    bestTimeEl.textContent = fmt(stats.best);
    countEl.textContent = stats.count || 0;
    renderList(historyList, stats.recent, formatRecentItem);
    renderList(topList, stats.top, formatTopItem);
}

function renderList(target, items = [], renderer) {
    target.innerHTML = "";
    if (!items.length) {
        const empty = document.createElement("li");
        empty.textContent = "暂时没有数据";
        target.appendChild(empty);
        return;
    }
    items.forEach((item) => {
        const li = document.createElement("li");
        renderer(li, item);
        target.appendChild(li);
    });
}

function formatRecentItem(el, item) {
    const date = formatTime(item.ts);
    el.innerHTML = `<span>${date}</span><strong>${Math.round(item.time)} ms</strong>`;
}

function formatTopItem(el, item) {
    const date = formatDateShort(item.ts);
    el.innerHTML = `<span>${Math.round(item.time)} ms</span><strong>${date}</strong>`;
}

function formatTime(isoString) {
    if (!isoString) return "--";
    return new Date(isoString).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", second: "2-digit" });
}

function formatDateShort(isoString) {
    if (!isoString) return "--";
    const d = new Date(isoString);
    return d.toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" });
}

function refreshStats() {
    fetch("/api/results")
        .then((res) => res.json())
        .then((payload) => {
            if (payload.ok) {
                updateStats(payload.data);
            }
        })
        .catch((err) => console.error(err));
}

setInterval(refreshStats, 15000);
